package com.vhall.component.service.inav.impl;

import com.vhall.component.entity.room.dto.RoomJoinsEntityDTO;
import com.vhall.component.entity.room.dto.RoomsEntityDTO;
import com.vhall.component.framework.common.exception.BusinessException;
import com.vhall.component.framework.common.utils.StringUtils;
import com.vhall.component.plugin.common.constant.RedisKey;
import com.vhall.component.plugin.common.constant.RoomConstant;
import com.vhall.component.plugin.common.exception.BizErrorCode;
import com.vhall.component.plugin.core.service.PaasService;
import com.vhall.component.service.room.RoomInnerService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.DefaultTypedTuple;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;

import java.math.BigDecimal;
import java.util.*;

/**
 * @author yongzheng.xu
 * @date 2021/6/23 20:46
 */
@Component
public class BaseService {

    @Autowired
    RoomInnerService roomInnerService;

    @Autowired
    RedisTemplate redisTemplate;

    @Autowired
    PaasService paasService;

    /**
     * 获取邀请列表
     *
     * @param roomId 房间id
     * @return 返回值 map，account_id是key，剩余有效时间是value.
     */
    Map<String, Long> getInviteList(String roomId) {
        Map<String, Long> result = new HashMap<>(16);
        long now = System.currentTimeMillis();
        String key = RedisKey.INTERACT_INVITE + roomId;
        long min = now - (RoomConstant.INVITE_VALID_TIME * 1000);
        long max = Long.MAX_VALUE;

        Set<DefaultTypedTuple<Long>> set = redisTemplate.opsForZSet().rangeByScoreWithScores(key, min, max);
        Assert.notNull(set, "参数异常");
        Iterator<DefaultTypedTuple<Long>> iterator = set.iterator();
        BigDecimal score;
        BigDecimal vs;
        BigDecimal ld = new BigDecimal(now);
        BigDecimal valid = new BigDecimal(RoomConstant.INVITE_VALID_TIME * 1000);
        while (iterator.hasNext()) {
            DefaultTypedTuple<Long> next = iterator.next();
            score = BigDecimal.valueOf(next.getScore());
            vs = score.add(valid).subtract(ld);
            result.put(String.valueOf(next.getValue()), vs.longValue());
        }
        return result;
    }

    /**
     * 查询当前参会用户信息
     *
     * @param roomId  房间编号
     * @param thirdId 三方用户id
     * @return joiner info
     */
    RoomJoinsEntityDTO getCurrentJoinUser(String roomId, Integer thirdId) {
        RoomJoinsEntityDTO joinUser = roomInnerService.getCurrentJoinUserByThirdId(roomId, thirdId);
        if (!joinUser.getRoleName().equals(RoomConstant.INTERACTION) && !joinUser.getRoleName().equals(RoomConstant.HOST)) {
            throw new BusinessException(BizErrorCode.BIZ_NO_PERMISSION);
        }
        return joinUser;
    }

    /**
     * 根据房间id及用户id获取参会信息
     *
     * @param roomId    房间id
     * @param accountId 参会用户id
     * @return 房间参与信息
     * @author yuanzh
     * @date 2021/9/15
     */
    RoomJoinsEntityDTO checkRoomJoinInfo(String roomId, Integer accountId) {
        RoomJoinsEntityDTO joinInfo = roomInnerService.getRoomJoinInfo(accountId, roomId);
        if (Objects.isNull(joinInfo)) {
            throw new BusinessException(BizErrorCode.BIZ_INVALID_USER);
        }
        return joinInfo;
    }

    /**
     * 获取房间PAAS频道id
     *
     * @param roomId 房间id
     * @return PAAS频道id
     * @author yuanzh
     * @date 2021/9/15
     */
    String getRoomChannelId(String roomId) {
        RoomsEntityDTO room = roomInnerService.getRoomInfo(roomId);
        if (Objects.isNull(room)) {
            throw new BusinessException(BizErrorCode.EMPTY_ROOM);
        }
        if (StringUtils.isEmpty(room.getChannelId())) {
            throw new BusinessException(BizErrorCode.EMPTY_INFO);
        }
        return room.getChannelId();
    }

    /**
     * 获取上麦数量
     *
     * @param joiner 参会用户信息
     */
    Integer getSpeakerCount(RoomJoinsEntityDTO joiner) {
        int result = 0;
        Map<Object, Object> speakerList = redisTemplate.opsForHash().entries(RedisKey.INTERACT_SPEAKER + joiner.getRoomId());
        int speakerCount = speakerList.size();
        Object docPermission = redisTemplate.opsForHash()
                .get(RedisKey.INTERACT_GLOBAL + joiner.getRoomId(), RoomConstant.DOC_PERMISSION);
        //文档操作人
        //文档操作人没有上麦也占位置
        Boolean flag = redisTemplate.opsForHash()
                .hasKey(RedisKey.INTERACT_SPEAKER + joiner.getRoomId(), String.valueOf(docPermission));
        if (docPermission != null && !flag && !String.valueOf(joiner.getAccountId()).equals(String.valueOf(docPermission))) {
            speakerCount++;
        }
        result = speakerCount;
        return result;
    }
}
